home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / x / animutil / xanim229.lha / xanim / xanim_fli.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-01-08  |  11.5 KB  |  474 lines

  1.  
  2. /*
  3.  * xanim_fli.c
  4.  *
  5.  * Copyright (C) 1990,1991,1992 by Mark Podlipec. 
  6.  * All rights reserved.
  7.  *
  8.  * This software may be freely copied, modified and redistributed
  9.  * without fee provided that this copyright notice is preserved 
  10.  * intact on all copies and modified copies.
  11.  * 
  12.  * There is no warranty or other guarantee of fitness of this software.
  13.  * It is provided solely "as is". The author(s) disclaim(s) all
  14.  * responsibility and liability with respect to this software's usage
  15.  * or its effect upon hardware or computer systems.
  16.  *
  17.  */
  18. #include <stdio.h>
  19. #include "mytypes.h"
  20. #include "xanim.h"
  21. #include "xanim_fli.h" 
  22.  
  23. void Read_Fli_Header();
  24. void Read_Fli_Frame_Header();
  25. void Read_Fli_File();
  26. void Decode_Fli_BRUN();
  27. void Decode_Fli_LC();
  28. void Read_Fli_COLOR();
  29. void Fli_Buffer_Action();
  30.  
  31. ULONG Fli_Get_Word();
  32. ULONG Fli_Get_HalfWord();
  33.  
  34. static Fli_Header fli_hdr;
  35. static Fli_Frame_Header frame_hdr;
  36.  
  37. void Read_Fli_Header(fp,fli_hdr)
  38. FILE *fp;
  39. Fli_Header *fli_hdr;
  40. {
  41.  int i;
  42.  
  43.  fli_hdr->size  = Fli_Get_Word(fp);
  44.  fli_hdr->magic = Fli_Get_HalfWord(fp);
  45.  fli_hdr->frames = Fli_Get_HalfWord(fp);
  46.  fli_hdr->width = Fli_Get_HalfWord(fp);
  47.  fli_hdr->height = Fli_Get_HalfWord(fp);
  48.  fli_hdr->res1 = Fli_Get_HalfWord(fp);
  49.  fli_hdr->flags = Fli_Get_HalfWord(fp);
  50.  fli_hdr->speed = Fli_Get_HalfWord(fp);
  51.  fli_hdr->next  = Fli_Get_Word(fp);
  52.  fli_hdr->frit  = Fli_Get_Word(fp);
  53.  for(i=0;i<102;i++) fgetc(fp);   /* ignore unused part of Fli_Header */
  54.  
  55.  imagex=fli_hdr->width;
  56.  imagey=fli_hdr->height;
  57.  if ( (fli_hdr->magic != 0xaf11) && (fli_hdr->magic != 0xaf12) )
  58.  {
  59.   fprintf(stderr,"imagex=%lx imagey=%lx\n",imagex,imagey);
  60.   fprintf(stderr,"Fli Header Error magic %lx not = 0xaf11\n",fli_hdr->magic);
  61.   TheEnd();
  62.  }
  63. }
  64.  
  65. void Read_Fli_Frame_Header(fp,frame_hdr)
  66. FILE *fp;
  67. Fli_Frame_Header *frame_hdr;
  68. {
  69.  int i;
  70.  
  71.  frame_hdr->size = Fli_Get_Word(fp);
  72.  frame_hdr->magic = Fli_Get_HalfWord(fp);
  73.  frame_hdr->chunks = Fli_Get_HalfWord(fp);
  74.  for(i=0;i<8;i++) fgetc(fp);    /* ignore unused part of Fli_Frame_Header */
  75.  
  76.  if (frame_hdr->magic != 0xf1fa)
  77.  {
  78.   fprintf(stderr,"Frame_Header Error magic %lx not = 0xf1fa\n",frame_hdr->magic);
  79.   TheEnd();
  80.  }
  81. }
  82.  
  83. void Read_Fli_File(fname)
  84. char *fname;
  85. {
  86.  FILE *fin;
  87.  int i,j,ret;
  88.  ACTION *act;
  89.  
  90.  
  91.  if ( (fin=fopen(fname,"r")) == 0)
  92.  { 
  93.   fprintf(stderr,"can't open Fli File %s for reading\n",fname); 
  94.   TheEnd();
  95.  }
  96.  
  97.  Read_Fli_Header(fin,&fli_hdr);
  98.  
  99. fprintf(stderr,"  x=%ld y=%ld Frames = %ld\n",fli_hdr.width,
  100.             fli_hdr.height,fli_hdr.frames);
  101.  
  102.  for(i=0;i<fli_hdr.frames;i++)
  103.  {
  104.   Read_Fli_Frame_Header(fin,&frame_hdr);
  105.  
  106.   if (frame_hdr.chunks==0)  /* this frame is for timing purposes */
  107.   {
  108.    if (verbose) fprintf(stderr," ACT_DELAY Chunk\n");
  109.    act = &action[action_cnt];
  110.    action_cnt++;
  111.    act->type = ACT_DELAY;
  112.    if (jiffy_flag) act->time = jiffy_flag;
  113.    else act->time = fli_hdr.speed * MS_PER_60HZ;
  114.    act->data = 0;
  115.   }
  116.   else /* this frame has real data in it */
  117.   {
  118.    /* Loop through chunks in the frame
  119.     */
  120.    for(j=0;j<frame_hdr.chunks;j++)
  121.    {
  122.     ULONG chunk_size,chunk_type;
  123.    
  124.     act = &action[action_cnt];
  125.     act->data = 0;
  126.     action_cnt++;
  127.  
  128.     chunk_size = Fli_Get_Word(fin);
  129.     chunk_type = Fli_Get_HalfWord(fin);
  130.     switch(chunk_type)
  131.     {
  132.      case FLI_COLOR:
  133.                  if (verbose) fprintf(stderr," FLI_COLOR Chunk\n");
  134.          Read_Fli_COLOR(fin,act);
  135.          break;
  136.  
  137.      case FLI_LC:
  138.          {
  139.           ACT_FLI_LC_HDR *fli_lc_hdr;
  140.  
  141.           if (verbose) fprintf(stderr," FLI_LC\n");
  142.           act->type = ACT_FLI_LC;
  143.            if (jiffy_flag) act->time = jiffy_flag;
  144.            else act->time = fli_hdr.speed * MS_PER_60HZ;
  145.            fli_lc_hdr = (ACT_FLI_LC_HDR *) 
  146.                 malloc( chunk_size-6 + sizeof(ACT_FLI_LC_HDR));
  147.            if (fli_lc_hdr == 0) TheEnd1("Read_Fli_LC: malloc failed");
  148.           act->data = (char *)(fli_lc_hdr);
  149.            ret = fread( fli_lc_hdr->data, (chunk_size-6), 1, fin);
  150.            if (ret != 1) TheEnd1("Read_Fli_LC: read failed");
  151.          }
  152.          break;
  153.  
  154.      case FLI_BLACK:
  155.                  if (verbose) fprintf(stderr," FLI_BLACK\n");
  156.          if (chunk_size > 6) 
  157.                        TheEnd1("Read_Fli_BLACK different than expected");
  158.          act->type = ACT_FLI_BLACK;
  159.           if (jiffy_flag) act->time = jiffy_flag;
  160.           else act->time = fli_hdr.speed * MS_PER_60HZ;
  161.           act->data = 0;
  162.          break;
  163.  
  164.      case FLI_BRUN:
  165.                  if (verbose) fprintf(stderr," FLI_BRUN\n");
  166.          act->type = ACT_FLI_BRUN;
  167.           if (jiffy_flag) act->time = jiffy_flag;
  168.           else act->time = fli_hdr.speed * MS_PER_60HZ;
  169.           act->data = (char *) malloc( chunk_size-6 );
  170.           if (act->data == 0) TheEnd1("Read_Fli_Brun: malloc failed");
  171.           ret = fread( act->data, (chunk_size-6), 1, fin);
  172.           if (ret != 1) TheEnd1("Read_Fli_Brun: read failed");
  173.          break;
  174.  
  175.      case FLI_COPY:
  176.                  if (verbose) fprintf(stderr," FLI_COPY\n");
  177.          act->type = ACT_FLI_COPY;
  178.           if (jiffy_flag) act->time = jiffy_flag;
  179.           else act->time = fli_hdr.speed * MS_PER_60HZ;
  180.           act->data = (char *) malloc( chunk_size-4 );
  181.           if (act->data == 0) TheEnd1("Read_Fli_COPY: malloc failed");
  182.           ret = fread( act->data, (chunk_size-4), 1, fin);
  183.           if (ret != 1) TheEnd1("Read_Fli_COPY: read failed");
  184.          break;
  185.       default: 
  186.  fprintf(stderr,"default size=%lx type=%lx\n",chunk_size,chunk_type);
  187.           TheEnd();
  188.     } /* end of switch */
  189.     if (chunk_size & 0x01)
  190.     {
  191.  fprintf(stderr,"chunk_size=%lx ODD\n",chunk_size);
  192.     }
  193.    } /* end of chunks is frame */
  194.   } /* end of not Timing Frame */
  195.  } /* end of frames in file */
  196.           
  197.  fclose(fin);
  198. }
  199.  
  200.  
  201. /*
  202.  * Routine to Decode a Fli BRUN chunk
  203.  */
  204. void Decode_Fli_BRUN(data,image_out)
  205. unsigned char *data,*image_out;
  206. {
  207.  ULONG i,j,k,packets,size,x,offset;
  208.  
  209.  for(i=0; i<imagey; i++)
  210.  {
  211.   offset = i * imagex;
  212.   packets = *data++;
  213.  
  214.   x=0;
  215.   for(j= 0; j < packets; j++)
  216.   {
  217.    size = *data++;
  218.    if (size & 0x80)             /* size < 0 so there is -size unique bytes */
  219.    {
  220.     size = 256-size; 
  221.     for(k= x; k < (x+size); k++) image_out[k+offset] = *data++;
  222.     x += size;   
  223.    }
  224.    else                         /* size is pos repeat next byte size times */
  225.    {
  226.     ULONG d;
  227.     d = *data++;
  228.     for(k= x; k < (x+size); k++) image_out[k+offset] = d;
  229.     x+=size;   
  230.    }
  231.   } /* end of packets per line */
  232.  } /* end of line */
  233. }
  234.  
  235. /*
  236.  * Routine to Decode an Fli LC chunk
  237.  */
  238. void Decode_Fli_LC(data,image_out,r_hdr)
  239. unsigned char *data,*image_out;
  240. REGION_HDR *r_hdr;
  241. {
  242.  ULONG i,j,k,packets,size,x,offset;
  243.  ULONG start,lines,skip,minx,maxx;
  244.  
  245.  start = *data++; start |= *data++ << 8;  /* lines to skip */
  246.  lines = *data++; lines |= *data++ << 8;  /* number of lines */
  247.  
  248.  r_hdr->ypos  = start;
  249.  r_hdr->ysize = lines;
  250.  minx = imagex; 
  251.  maxx = 0;
  252.  
  253.  for(i=start;i<(start+lines);i++)
  254.  {
  255.   offset = i * imagex;
  256.   packets = *data++;
  257.  
  258.   x=0;
  259.   for(j=0;j<packets;j++)
  260.   {
  261.    skip = *data++;   /* this is the skip count */
  262.    size = *data++;
  263.  
  264.    if (j==0) if (skip < minx) minx = skip;
  265.    x+=skip;
  266.    if (size==0) 
  267.    {
  268.     size = *data++;
  269. fprintf(stderr,"size==0 what to we do? next is %ld\n",size);
  270.     TheEnd();
  271.    }
  272.    if (size&0x80) /* next byte repeated -size times */
  273.    {
  274.     ULONG d;
  275.     size = 256-size; 
  276.     d = *data++;
  277.     for(k=x;k<(x+size);k++) image_out[k+offset] = d;
  278.     x+=size;   
  279.    }
  280.    else /* size is pos */
  281.    {
  282.     for(k=x;k<(x+size);k++) image_out[k+offset] = *data++;
  283.     x+=size;   
  284.    }
  285.   } /* end of packets per line */
  286.   if (x > maxx) maxx = x;
  287.  } /* end of line */
  288.  r_hdr->xpos = minx;
  289.  
  290.  if (maxx > imagex) maxx=imagex;
  291.  if (maxx > minx) r_hdr->xsize = maxx - minx;
  292.  else r_hdr->xsize = imagex - minx;
  293.  
  294.  if (debug_flag) fprintf(stderr,"xypos=<%ld %ld> xysize=<%ld %ld>\n",
  295.                          r_hdr->xpos,r_hdr->ypos,r_hdr->xsize,r_hdr->ysize);
  296. }
  297.  
  298. /*
  299.  * Routine to read an Fli COLOR chunk
  300.  */
  301. void Read_Fli_COLOR(fin,act)
  302. FILE *fin;
  303. ACTION *act;
  304. {
  305.  ULONG i,k,l,packets,skip,colors,cnt;
  306.  ColorReg *act_cmap;
  307.  CMAP_HDR *cmap_hdr;
  308.  
  309.  act->type = ACT_CMAP;
  310.  act->time = 0;
  311.  cmap_hdr = (CMAP_HDR *)
  312.                 malloc( CMAP_SIZE * sizeof(ColorReg) + sizeof(CMAP_HDR));
  313.  if (cmap_hdr == 0) TheEnd1("Fli_Read_COLOR: malloc failed\n");
  314.  act->data = (char *)cmap_hdr;
  315.  act_cmap = (ColorReg *)cmap_hdr->data;
  316.  cmap_hdr->cmap_size = imagec;
  317.  
  318.  for(i=0;i<CMAP_SIZE;i++) 
  319.  {
  320.   act_cmap[i].red   = cmap[i].red;
  321.   act_cmap[i].green = cmap[i].green;
  322.   act_cmap[i].blue  = cmap[i].blue;
  323.  }
  324.  
  325.  packets = Fli_Get_HalfWord(fin);
  326.  cnt=2;
  327.  for(k=0;k<packets;k++)
  328.  {
  329.   skip = fgetc(fin);
  330.   colors=fgetc(fin);
  331.   cnt+=2;
  332.   if (verbose) fprintf(stderr,"       skip=%ld colors=%ld\n",skip,colors);
  333.   if (colors==0) colors=256;
  334.   imagec=256;
  335.   for(l=skip;l<(skip+colors);l++)
  336.   {
  337.    act_cmap[l].red   = cmap[l].red   = fgetc(fin)<<2;
  338.    act_cmap[l].green = cmap[l].green = fgetc(fin)<<2;
  339.    act_cmap[l].blue  = cmap[l].blue  = fgetc(fin)<<2;
  340.   } /* end of colors */
  341.   cnt+= 3 * colors;
  342.  } /* end of packets */
  343.  if (cnt&0x01) fgetc(fin);  /* read pad byte if needed */
  344. }
  345.  
  346.  
  347. /*
  348.  * Routine to read buffer Fli Actions from action_start up to
  349.  * action_cnt.
  350.  */
  351. void Fli_Buffer_Action(action_start)
  352. int action_start;
  353. {
  354.  int i,pic_size;
  355.  char *pic,*t_pic;
  356.  ACTION *act;
  357.  
  358.  /* Allocate image buffer so deltas may be applied
  359.   */
  360.  pic_size = imagex * imagey;
  361.  pic = (char *) malloc( pic_size );
  362.  if (pic == 0) TheEnd1("BufferAction: malloc failed");
  363.  
  364.  for(i=action_start;i<action_cnt;i++)
  365.  {
  366.   act = &action[i];
  367.   switch(act->type)
  368.   {
  369.    case ACT_DELAY:    
  370.    case ACT_CMAP:    
  371.    case ACT_IMAGE:    
  372.    case ACT_FLI_COLOR:    
  373.    case ACT_FLI_COPY:    
  374.    case ACT_FLI_BLACK:    
  375.             /* Clear to color 0 
  376.              */
  377.             memset(pic,0x00,pic_size);
  378.  
  379.              t_pic = (char *) malloc( pic_size );
  380.             if (t_pic == 0) TheEnd1("BufferAction: malloc failed");
  381.             memset(t_pic,0x00,pic_size);
  382.  
  383.             act->type = ACT_IMAGE;  /* change to image */
  384.             free(act->data);        /* free up encoded */
  385.             act->data = t_pic;      /* point to image */
  386.             break;
  387.    case ACT_FLI_BRUN:    
  388.  
  389.             Decode_Fli_BRUN(act->data,pic);
  390.  
  391.              t_pic = (char *) malloc( pic_size );
  392.             if (t_pic == 0) TheEnd1("BufferAction: malloc failed");
  393.  
  394.             memcpy(t_pic,pic,pic_size);
  395.             act->type = ACT_IMAGE;  /* change to image */
  396.             free(act->data);        /* free up encoded */
  397.             act->data = t_pic;      /* point to image */
  398.  
  399.             break;
  400.    case ACT_FLI_LC:    
  401.             {
  402.              ACT_FLI_LC_HDR *fli_lc_hdr;
  403.              ACT_REGION_HDR *act_reg_hdr;
  404.  
  405.              fli_lc_hdr = (ACT_FLI_LC_HDR *)(act->data);
  406.              Decode_Fli_LC(fli_lc_hdr->data, pic, fli_lc_hdr);
  407.  
  408.              /* Since an FLI LC chunk typically changes less
  409.               * than the full image size, use a REGION to
  410.               * store the changes.
  411.               */
  412.               act_reg_hdr = (ACT_REGION_HDR *) 
  413.                 malloc(sizeof(ACT_REGION_HDR) + pic_size );
  414.              if (act_reg_hdr == 0) 
  415.                 TheEnd1("FLI BufferAction: malloc failed");
  416.              memcpy((void *)act_reg_hdr->data,
  417.                 (void *)pic, pic_size);
  418.              act->type = ACT_REGION;  /* change to region */
  419.              if (optimize_flag == TRUE)
  420.              {
  421.                act_reg_hdr->xpos  = fli_lc_hdr->xpos; 
  422.                act_reg_hdr->ypos  = fli_lc_hdr->ypos;
  423.                act_reg_hdr->xsize = fli_lc_hdr->xsize;
  424.                act_reg_hdr->ysize = fli_lc_hdr->ysize;
  425.              }
  426.              else
  427.                          {
  428.                            act_reg_hdr->xpos = 0;
  429.                            act_reg_hdr->ypos = 0;
  430.                            act_reg_hdr->xsize = imagex;
  431.                            act_reg_hdr->ysize = imagey;
  432.                          }
  433.  
  434.              free(act->data);         /* free up encoded */
  435.              act->data = (char *)act_reg_hdr; /* point to region */
  436.             }
  437.  
  438.             break;
  439.    default:        
  440.             fprintf(stderr,"Unknown not supported\n");
  441.   }
  442.  }
  443.  free(pic);
  444. }
  445.  
  446.  
  447. /* Routine to read a little endian long word.
  448.  * Note
  449.  */
  450. ULONG Fli_Get_Word(fp)
  451. FILE *fp;
  452. {
  453.  ULONG ret;
  454.  
  455.  ret =  fgetc(fp);
  456.  ret |= fgetc(fp) << 8;
  457.  ret |= fgetc(fp) << 16;
  458.  ret |= fgetc(fp) << 24;
  459.  return ret;
  460. }
  461.  
  462. /* Routine to read a little endian half word.
  463.  */
  464. ULONG Fli_Get_HalfWord(fp)
  465. FILE *fp;
  466. {
  467.  ULONG ret;
  468.  
  469.  ret =  fgetc(fp);
  470.  ret |= fgetc(fp) << 8;
  471.  return ret;
  472. }
  473.  
  474.